package cn.sola.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class DateUtil {
	private static final String format = "yyyy-MM-dd HH:mm:ss";
	
	/**
     * 把日期类型格式化成字符串
     * @param date
     * @param format
     * @return
     */
    public static String dateToString(Date date) {
        SimpleDateFormat formater = new SimpleDateFormat(format);
        try {
            return formater.format(date);
        } catch (Exception e) {
            return null;
        }
    }
    /**
     * 把日期类型格式化成字符串
     * @param date
     * @param format
     * @return
     */
    public static String dateToString(Date date,String format) {
        SimpleDateFormat formater = new SimpleDateFormat(format);
        try {
            return formater.format(date);
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 获取今年年初的
     * @return
     */
    public static Date getNowYearStart(){
    	Date date = getNowDate();
    	Calendar cal=Calendar.getInstance();
    	cal.setTime(date);
    	cal.set(Calendar.MONTH, 0);
    	cal.set(Calendar.DAY_OF_MONTH, 1);
    	cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
    	return cal.getTime();
    }
    
    /**
     * 获取几年的月份
     * @return
     */
    public static List<String> getNowYearMonthStart(){
    	String format = "yyyy-MM";
    	List<String> nowMmonth = new ArrayList<>();
    	Date date = getNowDate();
    	Calendar cal=Calendar.getInstance();
    	cal.setTime(date);
    	for(int index = 0 ; index < 12 ; index ++){
    		cal.set(Calendar.MONTH, index);
    		nowMmonth.add(dateToString(cal.getTime(), format));
    	}
    	return nowMmonth;
    }
    
    /**
     * 把时间转换成一天的开始时间
     * @param date
     * @return
     */
    public static Date getStartDate(Date date){
    	Calendar cal=Calendar.getInstance();
    	cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
    	return cal.getTime();
    }
    
    /**
     * 字符串格式 yyyy-MM-dd
     * @param date
     * @return
     * @throws ParseException
     */
    public static Date getStartDate(String date){
    	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");  
    	Calendar cal=Calendar.getInstance();
    	try {
			cal.setTime(format.parse(date));
			cal.set(Calendar.HOUR_OF_DAY, 0);
			cal.set(Calendar.MINUTE, 0);
			cal.set(Calendar.SECOND, 0);
			return cal.getTime();
		} catch (ParseException e) {
			return null;
		}
    }
    
    /**
     * yyyy-MM-dd 转化成对应时间
     * @param date
     * @return
     */
    public static Date getDate(String date){
    	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");  
    	try {
			return format.parse(date);
		} catch (ParseException e) {
			return null;
		}
    }
    
    /**
     * 把时间转换成一天的结束时间
     * @param date
     * @return
     */
    public static Date getEndDate(Date date){
    	Calendar cal=Calendar.getInstance();
    	cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 23);
		cal.set(Calendar.MINUTE, 59);
		cal.set(Calendar.SECOND, 59);
    	return cal.getTime();
    }
    
    /**
     * 字符串格式 yyyy-MM-dd
     * @param date
     * @return
     * @throws ParseException
     */
    public static Date getEndDate(String date){
    	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");  
    	Calendar cal=Calendar.getInstance();
    	try {
			cal.setTime(format.parse(date));
			cal.set(Calendar.HOUR_OF_DAY, 23);
			cal.set(Calendar.MINUTE, 59);
			cal.set(Calendar.SECOND, 59);
			return cal.getTime();
		} catch (ParseException e) {
			//e.printStackTrace();
			return null;
		}
    }
    
    /**
     * n天前的日期
     * @param day
     * @return
     */
    public static Date getBeforeDate(Integer day){
    	Date date=new Date();  
        Calendar calendar = Calendar.getInstance();  
        calendar.setTime(date);  
        calendar.add(Calendar.DAY_OF_YEAR, day  * -1);  
        date = calendar.getTime();  
        return date;
    }
    
    /**
     * 给定日期 n天前的日期
     * @param day
     * @param date
     * @return
     */
    public static Date getBeforeDate(Integer day,Date date){
    	Calendar calendar = Calendar.getInstance();  
    	calendar.setTime(date);  
    	calendar.add(Calendar.DAY_OF_YEAR, day * -1);  
    	date = calendar.getTime();  
    	return date;
    }
    
    /**
     * n天后的日期
     * @param day
     * @return
     */
    public static Date getAfterDate(Integer day){
    	Date date=new Date();  
    	Calendar calendar = Calendar.getInstance();  
    	calendar.setTime(date);  
    	calendar.add(Calendar.DAY_OF_YEAR, day);  
    	date = calendar.getTime();  
    	return date;
    }
    
    /**
     * n天后的日期
     * @param day
     * @return
     */
    public static Date getAfterDate(Integer day, Date date){
    	Calendar calendar = Calendar.getInstance();  
    	calendar.setTime(date);  
    	calendar.add(Calendar.DAY_OF_YEAR, day);  
    	date = calendar.getTime();  
    	return date;
    }
    
    /**
     * 得到昨天的日期
     * @return
     */
    public static Date getYesterdayDate(){
    	Date date=new Date();  
    	Calendar calendar = Calendar.getInstance();  
    	calendar.setTime(date);  
    	calendar.add(Calendar.DAY_OF_YEAR,-1);  
    	date = calendar.getTime();  
    	return date;
    }
    
    /**
     * 返回现在的日期
     * @return
     */
    public static Date getNowDate(){
    	return new Date();
    }
    
    /**
     * 通过天数计算范围内的所有天数
     * @param day
     * @return
     */
    public static List<String> getDateRangeByDay(int day){
    	List<String> date = new ArrayList<>();
    	for(int index = day - 1; index >= 0; index --){
    		date.add(dateToString(getBeforeDate(index), "yyyy-MM-dd"));
    	}
    	return date;
    }
    
    /**
     * 通过分页算出日期
     * @param pageNo
     * @param pageSize
     * @param day
     * @return
     */
    public static List<String> getDateRangeByPage(Integer pageNo, Integer pageSize,Integer day){
    	List<String> date = new ArrayList<>();
    	int sum = day;
    	if(pageNo * pageSize < day){
    		sum = pageNo * pageSize;
    	}
		for(int index = (pageNo - 1) * pageSize; index < sum; index ++){
			date.add(dateToString(getBeforeDate(index),"yyyy-MM-dd"));
		}
    	return date;
    }
    
    /**
     * 通过分页  和时间范围算出日期
     * @param pageNo
     * @param pageSize
     * @param startTime
     * @param endTime
     * @return
     */
    public static List<String> getDateRangeByPage(Integer pageNo, Integer pageSize,Date startTime,Date endTime){
    	List<String> date = new ArrayList<>();    	
    	int day = intervalDay(startTime,endTime) + 1;
    	int sum = day;
    	if(pageNo * pageSize < day){
    		sum = pageNo * pageSize;
    	}
		for(int index = (pageNo - 1) * pageSize; index < sum; index ++){
			date.add(dateToString(getBeforeDate(index,endTime),"yyyy-MM-dd"));
		}
    	return date;
    }
    
    /**
     * 通过计算的分页 起始页已经被计算  算出日期
     * @param pageNo
     * @param pageSize
     * @param day
     * @return
     */
    public static List<String> getDateRangeByCalculatePage(Integer pageNo, Integer pageSize,Integer day){
    	List<String> date = new ArrayList<>();
    	int sum = day;
    	if(pageNo + pageSize < day){
    		sum = pageNo + pageSize;
    	}
    	for(int index = pageNo; index < sum; index ++){
    		date.add(dateToString(getBeforeDate(index),"yyyy-MM-dd"));
    	}
    	return date;
    }
    
    /**
     * 通过计算的分页 起始页已经被计算 和时间范围算出日期
     * @param pageNo
     * @param pageSize
     * @param startTime
     * @param endTime
     * @return
     */
    public static List<String> getDateRangeByCalculatePage(Integer pageNo, Integer pageSize,Date startTime,Date endTime){
    	int day = intervalDay(startTime,endTime) + 1;
    	List<String> date = new ArrayList<>();
    	int sum = day;
    	if(pageNo + pageSize < day){
    		sum = pageNo + pageSize;
    	}
    	for(int index = pageNo; index < sum; index ++){
    		date.add(dateToString(getBeforeDate(index,endTime),"yyyy-MM-dd"));
    	}
    	return date;
    }
    
    /**
     * 比对时间
     * @param start
     * @param end
     * @return
     */
    public static boolean compareDate(Date start, Date end){
    	return start.getTime() > end.getTime() ? true : false;
    }
    
    /**
     * 时间间隔天数
     * @param start
     * @param end
     * @return
     */
    public static Integer intervalDay(Date start, Date end){
    	Calendar calendarStart = Calendar.getInstance();  
    	calendarStart.setTime(start);
    	Calendar calendarEnd = Calendar.getInstance();  
    	calendarEnd.setTime(end);
    	return calendarEnd.get(Calendar.DAY_OF_YEAR) - calendarStart.get(Calendar.DAY_OF_YEAR);
    }
    
    /**
     * 两日期间一共的天数
     * @param start
     * @param end
     * @return
     */
    public static Integer intervalDay2(Date start, Date end){
    	Calendar calendarStart = Calendar.getInstance();  
    	calendarStart.setTime(start);
    	Calendar calendarEnd = Calendar.getInstance();  
    	calendarEnd.setTime(end);
    	return calendarEnd.get(Calendar.DAY_OF_YEAR) - calendarStart.get(Calendar.DAY_OF_YEAR)+1;
    }
    
    /**
     * 获得星期
     * @Title: getWeekOfDate
     * @Description: TODO
     * @param @param dt
     * @param @return
     * @return String
     * @throws
     */
    public static String getWeekOfDate(Date dt) {
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);

        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;

        return weekDays[w];
    }
    
    /**
     * 与现在时间对比
     * @param date
     * @return
     */
    public static boolean compareDateOfNow(Date startDate,Date endDate){
    	Long start = startDate.getTime();
    	Long end  = endDate.getTime();
    	Long now = new Date().getTime();
    	if(now >= start && now <= end){
    		return true;
    	}else{
    		return false;
    	}
    }
    
    public static String getYYYYDDMM(Date date){
    	return dateToString(date,"yyyy-MM-dd");
    }
    public static List<String> getDateRangeByDate(Date start,Date end){
    	List<String> date = new ArrayList<>();
    	int count=intervalDay(start,end);
    	for(int i=count;i>=0;i--){
    		date.add(dateToString(getBeforeDate(i,end),"yyyy-MM-dd"));
    		getBeforeDate(count,end);
    	}
    	return date;
    }
    
    /**
     * 指定日期的当周周一
     * @param date
     * @return
     */
    public static Date getWeekStartDate(Date date){
    	Calendar cal = Calendar.getInstance();  
        cal.setTime(date);  
        // 判断要计算的日期是否是周日，如果是则减一天计算周六的，否则会出问题，计算到下一周去了  
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天  
        if (1 == dayWeek) {  
           cal.add(Calendar.DAY_OF_MONTH, -1);  
        }  
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一  
        cal.setFirstDayOfWeek(Calendar.MONDAY);  
        // 获得当前日期是一个星期的第几天  
        int day = cal.get(Calendar.DAY_OF_WEEK); 
        // 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值  
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);  
        //周一日期
        return cal.getTime();
    }
    
    /**
     * 给定日期 和 当周周一之间的日期
     * @param date
     * @return
     */
    public static List<String> getWeekStartDateToNow(Date date){
    	List<String> list = new ArrayList<>();
    	Date monday = getWeekStartDate(date);
    	int intervalDay = intervalDay2(monday,date);
    	for(int index = intervalDay; index > 0; index --){
    		list.add(dateToString(getBeforeDate(index - 1, date),"yyyyMMdd"));
    	}
    	return list;
    }
    
    public static Date getLastSunday() {  
        Calendar calendar = Calendar.getInstance();  
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;  
        int offset = 7 - dayOfWeek;  
        calendar.add(Calendar.DATE, offset - 7);  
        return calendar.getTime();  
    }
    
    public static Date getLastMonday() {  
    	Calendar calendar = Calendar.getInstance();  
    	int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;  
    	int offset = 1 - dayOfWeek;  
    	calendar.add(Calendar.DATE, offset - 7);  
    	return calendar.getTime();  
    }
    
    public static void main(String[] args) {
    	System.out.println(getWeekStartDateToNow(getDate("2018-08-20")));
    	System.out.println(getLastSunday());
    	System.out.println(getLastMonday());
	}
}
